unit u_ia;

interface

uses
  u_threadastar,
  u_astar,
  sysutils,
  u_timer,
  u_jresau,
  windows,
  u_partic,
  u_load;

type
  sel = record
    x,y,posi,posj,id : integer;
    exist : boolean;
    t: string;
  end;
  t_repere = record
    vu : boolean;
    rang : integer;
  end;

  t_nutella = record
    pos : t_move;
    emplacement : t_move;
  end;

//modif
  t_vie_en = record
    total: integer;
    actuel: integer;
  end;

  t_detect = record
    x : integer;
    y : integer;
    d : boolean;
  end;

  C_ennemi = class
    private
      timer           : C_timer;
      attaque         : C_timer;
      bouge           : C_timer;
      thread          : fred_aster;
      objet           : objet_map;  // _type et niveau uniquement
      dep             : t_move;
      vu              : boolean;
      id_kres         : integer;
      orientation     : integer;
      tlargeur,tlongueur : integer;
      peur            : integer;
      detect          : t_detect;
      deplacement     : boolean;
      frequence       : integer;
      porte           : integer;
      particle        : tparticle;
    public
      vie             : t_vie_en;
      vivant          : boolean;
      posi,posj,petg  : integer;
      emplacement     : t_move;
      function traitement(etge,tx,ty,joueurx,joueury : integer ;var mapobj : t_map ; var ma : t_map_obj ; kam : boolean) : boolean;
      procedure traitement_k(etge,tx,ty,joueurx,joueury : integer ;var mapobj : t_map ;var ma : t_map_obj ; kam : boolean);
      procedure traitement_kres(etge,tx,ty,joueurx,joueury : integer; joueurs : t_player ;var mapobj : t_map ;var ma : t_map_obj ; kam : t_repere);
      procedure traitement_wres(etge,tx,ty : integer; joueurs : t_player ;var mapobj : t_map ;var ma : t_map_obj);
      function traitementres(etge,tx,ty : integer; joueurs : t_player ;var mapobj : t_map ; var ma : t_map_obj) : t_repere;
      procedure traitement_w(etge,tx,ty,joueurx,joueury : integer ;var mapobj : t_map ;var ma : t_map_obj);
      procedure fuir();
      procedure attak(x,y : integer);
  end;

  T_tabennemi = array of C_ennemi;
  t_pipi = record
  tab : t_tabennemi;
  t : string;
end;

  C_ennemis = class
    private
      cyphers   : T_tabennemi;
      kamikazes : T_tabennemi;
      warriors  : T_tabennemi;
      c,w,k     : boolean;
    public
      procedure tableaux(etge : integer;var mapobj : t_map_obj);
      procedure detection(det : t_detect);
      procedure appel_champ(etge,taillemx,taillemy,joueurx,joueury : integer;var mapobj : t_map;var ma : t_map_obj);
      procedure appel_champres(etge,tx,ty : integer ; joueurs : t_player ; var mapobj : t_map; var ma : t_map_obj);
      function acces(i,tab : integer) : t_nutella;
      function longueur(tab : integer) : integer;
      function recu_tab(n : integer) : t_tabennemi;
      function copy_tab(tab : t_tabennemi; n : integer): boolean;
      function suicide_ennemi(a,b,c,x,y,z,deg : integer; var mouton : t_map; var map : t_map_obj) : t_pipi;
      procedure aggro(selection_pos : sel; player_x,player_y : integer);
      procedure dispose();
  end;

implementation
uses
u_engine, u_player;
////////////////////////////////////////////////////////////////////////////////

//modif

procedure c_ennemis.aggro(selection_pos : sel; player_x,player_y : integer);
begin
  if selection_pos.t = 'Espion' then
    self.cyphers[selection_pos.posj].fuir()
  else
    if selection_pos.t = 'Kamikaze' then
      self.kamikazes[selection_pos.posj].attak(player_x,player_y)
    else
      self.warriors[selection_pos.posj].attak(player_x,player_y);
end;

procedure C_ennemi.attak(x,y : integer);
begin
  self.vu := true;
end;

procedure C_ennemi.fuir();
begin
  self.thread.finish;
  self.thread.init(self.emplacement.x,self.emplacement.y,random(mymesh.taillex),random(mymesh.tailley),self.petg,mymesh.taillex,mymesh.tailley,mymesh.map2);
  self.thread.Execute;
  self.timer.init(100);
end;

function C_ennemis.suicide_ennemi(a,b,c,x,y,z,deg : integer; var mouton : t_map; var map : t_map_obj) : t_pipi;
var
  i : integer;
begin
  setlength(result.tab,0);
  if mouton[z,x,y]._type = 'Espion' then
    begin
    result.tab := cyphers;
    result.t := 'Espion';
    end
  else
    if mouton[z,x,y]._type = 'Kamikaze' then
      begin
      result.tab := kamikazes;
      result.t := 'Kamikaze';
      end
    else
      begin
      result.tab := warriors;
      result.t := 'warriors';
      end;
  i := 0;
  while (i <= high(result.tab)) and (not((result.tab[i].emplacement.x = x) and (result.tab[i].emplacement.y = y))) do
    i := i+1;
  if i <= high(result.tab) then
    begin
      result.tab[i].vie.actuel := result.tab[i].vie.actuel - deg;
      if result.tab[i].vie.actuel < 1 then
        begin
          if (i = high(result.tab)) and (myplayer.selection_pos.posj = i) then
            myplayer.selection_pos.exist := false;
          mouton[z,x,y]._type := 'none';
          mouton[z,x,y].nom := 'none';
          map[z][result.tab[i].posi].tab_etage[result.tab[i].posj] := map[z][result.tab[i].posi].tab_etage[high(map[z][result.tab[i].posi].tab_etage)];
          result.tab[i] := result.tab[high(result.tab)];
          result.tab[i].posj := i;
          setlength(map[z][result.tab[i].posi].tab_etage,length(map[z][result.tab[i].posi].tab_etage)-1);
          setlength(result.tab,length(result.tab)-1);
          myplayer.clientorserveur.send_ennemi_del_pos(inttostr(x),inttostr(y),inttostr(z));
        end;
    end;
end;


procedure C_ennemis.appel_champres;
var
  i,k : integer;
  rep : t_repere;
  w: Integer;
begin
  self.c := false;
  for i := low(self.cyphers) to high(self.cyphers) do
    begin
      rep := self.cyphers[i].traitementres(etge,tx,ty,joueurs,mapobj,ma);
      if rep.vu and (length(self.kamikazes) > 0) then
        begin
          self.k := false;
          if (joueurs[rep.rang].x + 1) < tx then
            begin
              k := random(high(kamikazes));
              self.kamikazes[k].traitement_kres(etge,tx,ty,joueurs[rep.rang].x+1,joueurs[rep.rang].y,joueurs,mapobj,ma,rep);
              if (joueurs[rep.rang].y + 1) < ty then
                begin
                  k := random(high(kamikazes));
                  self.kamikazes[k].traitement_kres(etge,tx,ty,joueurs[rep.rang].x+1,joueurs[rep.rang].y+1,joueurs,mapobj,ma,rep);
                end;
              if (joueurs[rep.rang].y - 1) > 0 then
                begin
                  k := random(high(kamikazes));
                  self.kamikazes[k].traitement_kres(etge,tx,ty,joueurs[rep.rang].x+1,joueurs[rep.rang].y-1,joueurs,mapobj,ma,rep);
                end;
            end;
          if (joueurs[rep.rang].x - 1) > 0 then
            begin
              k := random(high(kamikazes));
              self.kamikazes[k].traitement_kres(etge,tx,ty,joueurs[rep.rang].x-1,joueurs[rep.rang].y,joueurs,mapobj,ma,rep);
              if (joueurs[rep.rang].y + 1) < ty then
                begin
                  k := random(high(kamikazes));
                  self.kamikazes[k].traitement_kres(etge,tx,ty,joueurs[rep.rang].x-1,joueurs[rep.rang].y+1,joueurs,mapobj,ma,rep);
                end;
              if (joueurs[rep.rang].y - 1) > 0 then
                begin
                  k := random(high(kamikazes));
                  self.kamikazes[k].traitement_kres(etge,tx,ty,joueurs[rep.rang].x-1,joueurs[rep.rang].y-1,joueurs,mapobj,ma,rep);
                end;
            end;
          self.k := true;
        end;
    end;
  self.c := true;
  self.k := false;
  if length(self.kamikazes) > 0 then
    begin
      for k := low(self.kamikazes) to high(self.kamikazes) do
        begin
          self.kamikazes[k].traitement_kres(etge,tx,ty,-1,-1,joueurs,mapobj,ma,rep);
          self.kamikazes[k].particle.Render_ennemi(myform._3D_device);
        end;
    end;
  self.k := true;
  self.w := false;
  if length(self.warriors) > 0 then
    begin
      for w := low(self.warriors) to high(self.warriors) do
        begin
          if self.warriors[w].peur in [0..3] then
            self.warriors[w].traitement_wres(etge,tx,ty,joueurs,mapobj,ma)
          else
            if self.warriors[w].peur in [4..7] then
              self.warriors[w].traitement_wres(etge,tx,ty,joueurs,mapobj,ma)
            else
              self.warriors[w].traitement_wres(etge,tx,ty,joueurs,mapobj,ma);
          self.warriors[w].particle.Render_ennemi(myform._3D_device);
        end;
    end;
    self.w := true;
end;

function C_ennemi.traitementres(etge,tx,ty : integer; joueurs : t_player ;var mapobj : t_map ;var ma : t_map_obj) : t_repere;
var
  i,j,k : integer;
  d : t_move;
begin
  result.vu := false;
  if self.thread.is_finished then
    begin
      self.bouge.init(30000);
      if self.timer.test then
        begin
          d := thread.fred.retourne_ck(self.emplacement.x,self.emplacement.y,etge,mapobj);
          if (d.x <> self.emplacement.x) or (d.y <> self.emplacement.y) then
            begin
              // serveur
              myplayer.clientorserveur.send_ennemi_move(inttostr(emplacement.x), inttostr(emplacement.y), inttostr(etge), inttostr(d.x), inttostr(d.y), inttostr(etge));
              mapobj[etge,self.emplacement.x,self.emplacement.y]._type := 'none';
              mapobj[etge,self.emplacement.x,self.emplacement.y].nom := 'none';
              self.emplacement := d;
              ma[petg][posi].tab_etage[posj].x := self.emplacement.x;
              ma[petg][posi].tab_etage[posj].y := self.emplacement.y;
              mapobj[etge,self.emplacement.x,self.emplacement.y] := ma[petg][posi].objet;
              self.frequence := getcurrenttime;
            end;
          if length(thread.fred.chemin) = 0 then
            begin
              self.thread.finish;
              self.timer.init(5000);
            end;
        end;
    end
  else
    begin
      if self.bouge.test then
        begin
          self.thread.init(self.emplacement.x,self.emplacement.y,self.dep.x,self.dep.y,etge,tx,ty,ma);
          self.thread.Execute;
          self.timer.init(100);
        end
      else
        begin
      if self.timer.test then
        begin
          self.orientation := (self.orientation + 1) mod 4;
        end;
    end;
  k := low(joueurs);
  while (k <= high(joueurs)) and (not result.vu) do
    begin
      case self.orientation of
        0 : begin
          if (joueurs[k].x >= self.emplacement.x-(self.tlargeur div 2)) and
            (joueurs[k].x <= self.emplacement.x+(self.tlargeur div 2)) and
            (joueurs[k].y <= self.emplacement.y) and
            (joueurs[k].y >= self.emplacement.y-self.tlongueur)
          then
            begin
              result.vu := true;
              result.rang := k;
            end;
        end;
        1 : begin
          if (joueurs[k].x >= self.emplacement.x-(self.tlargeur div 2)) and
            (joueurs[k].x <= self.emplacement.x+(self.tlargeur div 2)) and
            (joueurs[k].y <= self.emplacement.y) and
            (joueurs[k].y >= self.emplacement.y-self.tlongueur)
          then
            begin
              result.vu := true;
              result.rang := k;
            end;
        end;
        2 : begin
          if (joueurs[k].x >= self.emplacement.x-(self.tlargeur div 2)) and
            (joueurs[k].x <= self.emplacement.x+(self.tlargeur div 2)) and
            (joueurs[k].y >= self.emplacement.y) and
            (joueurs[k].y <= self.emplacement.y+self.tlongueur)
          then
            begin
              result.vu := true;
              result.rang := k;
            end;
        end;
        3 : begin
          if (joueurs[k].y >= self.emplacement.y-(self.tlargeur div 2)) and
            (joueurs[k].y <= self.emplacement.y+(self.tlargeur div 2)) and
            (joueurs[k].x >= self.emplacement.x) and
            (joueurs[k].x <= self.emplacement.x+self.tlongueur)
          then
            begin
              result.vu := true;
              result.rang := k;
            end;
        end;
      end;
      k := k + 1;
    end;
  if result.vu then
    begin
      self.thread.finish;
      i := random(tx);
      j := random(ty);
      thread.init(self.emplacement.x,self.emplacement.y,i,j,etge,tx,ty,ma);
      thread.execute;
      self.timer.init(100);
      self.frequence := getcurrenttime;
    end;
    end;
end;

procedure C_ennemi.traitement_kres(etge,tx,ty,joueurx,joueury : integer; joueurs : t_player ;var mapobj : t_map ;var ma : t_map_obj ; kam : t_repere);
var
  d : t_move;
  k,i : integer;
begin
  if thread.is_finished then
    begin
      if self.timer.test then
        begin
          d := thread.fred.retourne_ck(self.emplacement.x,self.emplacement.y,etge,mapobj);
          if (d.x <> self.emplacement.x) or (d.y <> self.emplacement.y) then
            begin
              myplayer.clientorserveur.send_ennemi_move(inttostr(emplacement.x), inttostr(emplacement.y), inttostr(etge), inttostr(d.x), inttostr(d.y), inttostr(etge));
              mapobj[etge,self.emplacement.x,self.emplacement.y]._type := 'none';
              mapobj[etge,self.emplacement.x,self.emplacement.y].nom := 'none';
              self.emplacement := d;
              ma[petg][posi].tab_etage[posj].x := self.emplacement.x;
              ma[petg][posi].tab_etage[posj].y := self.emplacement.y;
              mapobj[etge,self.emplacement.x,self.emplacement.y] := ma[petg][posi].objet;
              self.frequence := getcurrenttime;
            end;
          if length(thread.fred.chemin) = 0 then
            begin
              self.thread.finish;
              self.timer.init(5000);
            end;
        end;
    end
  else
    begin
      if kam.vu or self.vu then
        begin
        if (self.porte >= (self.thread.fred.pythagore(self.emplacement.x,self.emplacement.y,joueurs[self.id_kres].x,joueurs[self.id_kres].y))) and (self.attaque.test) then
          begin
           self.particle.add_part_ennemi(100,self.emplacement.x,self.emplacement.y,joueurs[self.id_kres].x,joueurs[self.id_kres].y);
           myplayer.suicide(10,self.emplacement.x,self.emplacement.y,joueurs[self.id_kres].x,joueurs[self.id_kres].y);
           self.attaque.init(2000);
          end
        else
          begin
            thread.init(self.emplacement.x,self.emplacement.y,joueurs[self.id_kres].x,joueurs[self.id_kres].y,etge,tx,ty,ma);
            thread.Execute;
            self.timer.init(200);
            self.frequence := getcurrenttime;
          end;
        end
      else
        begin
          if self.timer.test then
            begin
              self.thread.init(self.emplacement.x,self.emplacement.y,self.dep.x,self.dep.y,etge,tx,ty,ma);
              self.thread.Execute;
              self.timer.init(200);
              self.frequence := getcurrenttime;
            end
          else
            begin
              i := 0;
              while (i < high(joueurs)) and not self.vu do
                begin
                  case self.orientation of
                    0 : begin
                      if (joueurs[i].x >= self.emplacement.x-(self.tlargeur div 2)) and
                        (joueurs[i].x <= self.emplacement.x+(self.tlargeur div 2)) and
                        (joueurs[i].y <= self.emplacement.y) and
                        (joueurs[i].y >= self.emplacement.y-self.tlongueur)
                      then
                        begin
                          self.vu := true;
                          self.id_kres := i;
                        end;
                    end;
                    1 : begin
                      if (joueurs[i].x >= self.emplacement.x-(self.tlargeur div 2)) and
                        (joueurs[i].x <= self.emplacement.x+(self.tlargeur div 2)) and
                        (joueurs[i].y <= self.emplacement.y) and
                        (joueurs[i].y >= self.emplacement.y-self.tlongueur)
                      then
                        begin
                          self.vu := true;
                          self.id_kres := i;
                        end;
                    end;
                    2 : begin
                      if (joueurs[i].x >= self.emplacement.x-(self.tlargeur div 2)) and
                        (joueurs[i].x <= self.emplacement.x+(self.tlargeur div 2)) and
                        (joueurs[i].y >= self.emplacement.y) and
                        (joueurs[i].y <= self.emplacement.y+self.tlongueur)
                      then
                        begin
                          self.vu := true;
                          self.id_kres := i;
                        end;
                    end;
                    3 : begin
                      if (joueurs[i].y >= self.emplacement.y-(self.tlargeur div 2)) and
                        (joueurs[i].y <= self.emplacement.y+(self.tlargeur div 2)) and
                        (joueurs[i].x >= self.emplacement.x) and
                        (joueurs[i].x <= self.emplacement.x+self.tlongueur)
                      then
                        begin
                          self.vu := true;
                          self.id_kres := i;
                        end;
                    end;
                  end;
                  i := i + 1;
                end;
            end;
        end;
    end;
end;

procedure C_ennemi.traitement_wres(etge,tx,ty : integer ;joueurs : t_player;var mapobj : t_map ;var ma : t_map_obj);
var
  d : t_move;
  k : integer;
begin
  self.vu := false;
  k := 0;
  while (k <= high(joueurs)) and not (self.vu) do
    begin
      case self.orientation of
        0 : begin
          if (joueurs[k].x >= self.emplacement.x-(self.tlargeur div 2)) and
            (joueurs[k].x <= self.emplacement.x+(self.tlargeur div 2)) and
            (joueurs[k].y <= self.emplacement.y) and
            (joueurs[k].y >= self.emplacement.y-self.tlongueur)
          then
            begin
              self.vu := true;
              self.id_kres := k;
            end;
        end;
        1 : begin
          if (joueurs[k].x >= self.emplacement.x-(self.tlargeur div 2)) and
            (joueurs[k].x <= self.emplacement.x+(self.tlargeur div 2)) and
            (joueurs[k].y <= self.emplacement.y) and
            (joueurs[k].y >= self.emplacement.y-self.tlongueur)
          then
            begin
              self.vu := true;
              self.id_kres := k;
            end;
        end;
        2 : begin
          if (joueurs[k].x >= self.emplacement.x-(self.tlargeur div 2)) and
            (joueurs[k].x <= self.emplacement.x+(self.tlargeur div 2)) and
            (joueurs[k].y >= self.emplacement.y) and
            (joueurs[k].y <= self.emplacement.y+self.tlongueur)
          then
            begin
              self.vu := true;
              self.id_kres := k;
            end;
        end;
        3 : begin
          if (joueurs[k].y >= self.emplacement.y-(self.tlargeur div 2)) and
            (joueurs[k].y <= self.emplacement.y+(self.tlargeur div 2)) and
            (joueurs[k].x >= self.emplacement.x) and
            (joueurs[k].x <= self.emplacement.x+self.tlongueur)
          then
            begin
              self.vu := true;
              self.id_kres := k;
            end;
        end;
      end;
      k := k+1;
    end;
  if (thread.is_finished) and (not self.vu) then
    begin
      if self.timer.test then
        begin
          d := thread.fred.retourne_ck(self.emplacement.x,self.emplacement.y,etge,mapobj);
          if (d.x <> self.emplacement.x) or (d.y <> self.emplacement.y) then
            begin
              //Envoi nouvelle position de l'ennemi
              myplayer.clientorserveur.send_ennemi_move(inttostr(emplacement.x), inttostr(emplacement.y), inttostr(etge), inttostr(d.x), inttostr(d.y), inttostr(etge));
              mapobj[etge,self.emplacement.x,self.emplacement.y]._type := 'none';
              mapobj[etge,self.emplacement.x,self.emplacement.y].nom := 'none';
              self.emplacement := d;
              ma[petg][posi].tab_etage[posj].x := self.emplacement.x;
              ma[petg][posi].tab_etage[posj].y := self.emplacement.y;
              mapobj[etge,self.emplacement.x,self.emplacement.y] := ma[petg][posi].objet;
              self.frequence := getcurrenttime;
            end;
          if length(thread.fred.chemin) = 0 then
            begin
              self.thread.finish;
              self.timer.init(5000);
            end;
        end;
    end
  else
    begin
      if self.vu then
        begin
          self.particle.add_part_ennemi(100,self.emplacement.x,self.emplacement.y,joueurs[self.id_kres].x,joueurs[self.id_kres].y);
          myplayer.suicide(10,self.emplacement.x,self.emplacement.y,joueurs[self.id_kres].x,joueurs[self.id_kres].y);
          self.attaque.init(2000);
        end
      else
        if self.timer.test then
          begin
            self.thread.init(self.emplacement.x,self.emplacement.y,random(tx),random(ty),etge,tx,ty,ma);
            self.thread.Execute;
            self.timer.init(200);
            self.frequence := getcurrenttime;
          end;
    end;
end;

////////////////////////////////////////////////////////////////////////////////
//                                 C_ennemis                                  //
////////////////////////////////////////////////////////////////////////////////
function c_ennemis.recu_tab(n : integer) : t_tabennemi;
begin
  if n = 1 then
    result := self.cyphers
  else
    if n = 2 then
      result := self.kamikazes
    else
      result := self.warriors;
end;

function c_ennemis.copy_tab(tab : t_tabennemi; n : integer) : boolean;
begin
  if n = 1 then
    begin
      result := self.c;
      if result then
        self.cyphers := tab
    end
  else
    if n = 2 then
      begin
        result := self.k;
        if self.k then
          self.kamikazes := tab
      end
    else
      if n = 3 then
        begin
          result := self.w;
          if result then
            self.warriors := tab;
        end;
end;

procedure C_ennemis.tableaux(etge : integer;var mapobj : t_map_obj);
var
  i,j : integer;
begin
  for i := low(mapobj[etge]) to high(mapobj[etge]) do
    begin
      if mapobj[etge][i].objet._type = 'Espion' then
        begin
          setlength(self.cyphers,length(mapobj[etge][i].tab_etage));
          for j := low(self.cyphers) to high(self.cyphers) do
            begin
              self.cyphers[j]                 := C_ennemi.create;
              self.cyphers[j].timer           := C_timer.Create;
              self.cyphers[j].bouge           := C_timer.Create;
              self.cyphers[j].bouge.init(30000);
              self.cyphers[j].timer.init(5000);
              self.cyphers[j].objet           := mapobj[etge][i].objet;
              self.cyphers[j].emplacement.x   := mapobj[etge][i].tab_etage[j].x;
              self.cyphers[j].emplacement.y   := mapobj[etge][i].tab_etage[j].y;
              self.cyphers[j].dep.x           := mapobj[etge][i].tab_etage[j].x;
              self.cyphers[j].dep.y           := mapobj[etge][i].tab_etage[j].y;
              self.cyphers[j].orientation     := 1;
              self.cyphers[j].tlargeur        := 5;
              self.cyphers[j].tlongueur       := 15;
              self.cyphers[j].posi            := i;
              self.cyphers[j].posj            := j;
              self.cyphers[j].frequence       := 0;
              self.cyphers[j].petg            := etge;
              self.cyphers[j].deplacement     := false;
              self.cyphers[j].vie.actuel      := 20;
              self.warriors[j].vie.total      := 20;
              self.cyphers[j].thread          := fred_aster.create;
            end;
        end
      else
        if mapobj[etge][i].objet._type = 'Kamikaze' then
        begin
          setlength(self.kamikazes,length(mapobj[etge][i].tab_etage));
          for j := low(self.kamikazes) to high(self.kamikazes) do
            begin
              self.kamikazes[j]                 := C_ennemi.create;
              self.kamikazes[j].timer           := C_timer.Create;
              self.kamikazes[j].attaque         := C_timer.Create;
              self.kamikazes[j].bouge           := C_timer.Create;
              self.kamikazes[j].attaque.init(4000);
              //TITOU SUCE DES ZIZIS GLACES
              self.kamikazes[j].objet           := mapobj[etge][i].objet;
              self.kamikazes[j].emplacement.x   := mapobj[etge][i].tab_etage[j].x;
              self.kamikazes[j].emplacement.y   := mapobj[etge][i].tab_etage[j].y;
              self.kamikazes[j].dep.x           := mapobj[etge][i].tab_etage[j].x;
              self.kamikazes[j].dep.y           := mapobj[etge][i].tab_etage[j].y;
              self.kamikazes[j].orientation     := random(4);
              //JE TE LOVE MON TITOU
              self.kamikazes[j].tlargeur        := 5;        //      /
              self.kamikazes[j].tlongueur       := 10;      //     /  /
              self.kamikazes[j].posi            := i;      //      /  /    TON ZIZI!!
              self.kamikazes[j].posj            := j;     //       /  /
              self.kamikazes[j].petg            := etge; //     // /  / //
              self.kamikazes[j].frequence       := 0;         // //  //  //
              self.kamikazes[j].deplacement     := false;      //      //
              self.kamikazes[j].vie.actuel             := 100;
              self.warriors[j].vie.total        := 100;
              self.kamikazes[j].thread          := fred_aster.create;
              //KICK MY ASS NOW!
              self.kamikazes[j].vu              := false;
              self.kamikazes[j].porte           := 5;
              //WOW IS BAD
              self.kamikazes[j].particle        := tparticle.Create(myform._3D_device);
            end;
        end
      else
        if mapobj[etge][i].objet._type = 'Ennemi dynamique' then
          begin
            setlength(self.warriors,length(mapobj[etge][i].tab_etage));
            for j := low(self.warriors) to high(self.warriors) do
              begin
                self.warriors[j]                 := C_ennemi.create;
                self.warriors[j].timer           := C_timer.Create;
                self.warriors[j].attaque         := C_timer.Create;
                self.warriors[j].bouge           := C_timer.Create;
                self.warriors[j].attaque.init(3000);
                self.warriors[j].objet           := mapobj[etge][i].objet;
                self.warriors[j].emplacement.x   := mapobj[etge][i].tab_etage[j].x;
                self.warriors[j].emplacement.y   := mapobj[etge][i].tab_etage[j].y;
                self.warriors[j].orientation     := random(4);
                self.warriors[j].tlargeur        := 5;
                self.warriors[j].tlongueur       := 10;
                self.warriors[j].peur            := 0;
                self.warriors[j].posi            := i;
                self.warriors[j].posj            := j;
                self.warriors[j].petg            := etge;
                self.warriors[j].frequence       := 0;
                self.warriors[j].deplacement     := false;
                self.warriors[j].vie.actuel      := 100;
                self.warriors[j].vie.total      := 100;
                self.warriors[j].thread          := fred_aster.create;
                self.warriors[j].vu              := false;
                self.warriors[j].porte           := 5;
                self.warriors[j].particle        := tparticle.Create(myform._3D_device);
              end;
          end;
    end;
  if myplayer.game_type = 's' then
    myplayer.ngbennemis := length(self.cyphers) + length(self.kamikazes) + length(self.warriors);
end;

procedure c_ennemis.dispose();
var
  i : integer;
begin
  for i := low(self.cyphers) to high(self.cyphers) do
  begin
    cyphers[i].timer.Free;
    cyphers[i].bouge.Free;
    cyphers[i].thread.Terminate;
    cyphers[i].thread.Free;
  end;
  for i := low(self.kamikazes) to high(self.kamikazes) do
  begin
    kamikazes[i].timer.Free;
    kamikazes[i].attaque.Free;
    kamikazes[i].bouge.Free;
    kamikazes[i].thread.Terminate;
    kamikazes[i].thread.Free;
    kamikazes[i].particle.Free;
  end;
  for i := low(self.warriors) to high(self.warriors) do
  begin
    warriors[i].timer.Free;
    warriors[i].attaque.Free;
    warriors[i].bouge.Free;
    warriors[i].thread.Terminate;
    warriors[i].thread.Free;
    warriors[i].particle.Free;
  end;
end;

procedure C_ennemis.detection(det : t_detect);
var
  i : integer;
begin
  for i := low(self.kamikazes) to high(self.kamikazes) do
    self.kamikazes[i].detect := det;
  for i := low(self.warriors) to high(self.warriors) do
    begin
      if self.warriors[i].peur < 7 then
        self.warriors[i].detect := det;
    end;
end;

procedure C_ennemis.appel_champ;
var
  i,k : integer;
  vu : boolean;
  w: Integer;
begin
  self.c := false;
  for i := low(self.cyphers) to high(self.cyphers) do
    begin
      vu := self.cyphers[i].traitement(etge,taillemx,taillemy,joueurx,joueury,mapobj,ma,false);
      if vu and (length(self.kamikazes) > 0) then
        begin
          self.k := false;
          if (joueurx + 1) < taillemx then
            begin
              k := random(high(kamikazes));
              self.kamikazes[k].traitement_k(etge,taillemx,taillemy,joueurx+1,joueury,mapobj,ma,vu);
              if (joueury + 1) < taillemy then
                begin
                  k := random(high(kamikazes));
                  self.kamikazes[k].traitement_k(etge,taillemx,taillemy,joueurx+1,joueury+1,mapobj,ma,vu);
                end;
              if (joueury - 1) > 0 then
                begin
                  k := random(high(kamikazes));
                  self.kamikazes[k].traitement_k(etge,taillemx,taillemy,joueurx+1,joueury-1,mapobj,ma,vu);
                end;
            end;
          if (joueurx - 1) > 0 then
            begin
              k := random(high(kamikazes));
              self.kamikazes[k].traitement_k(etge,taillemx,taillemy,joueurx-1,joueury,mapobj,ma,vu);
              if (joueury + 1) < taillemy then
                begin
                  k := random(high(kamikazes));
                  self.kamikazes[k].traitement_k(etge,taillemx,taillemy,joueurx-1,joueury+1,mapobj,ma,vu);
                end;
              if (joueury - 1) > 0 then
                begin
                  k := random(high(kamikazes));
                  self.kamikazes[k].traitement_k(etge,taillemx,taillemy,joueurx-1,joueury-1,mapobj,ma,vu);
                end;
            end;
          self.k := true;            
        end;
    end;
  self.c := true;
  self.k := false;
  if length(self.kamikazes) > 0 then
    begin
      for k := low(self.kamikazes) to high(self.kamikazes) do
        begin
          self.kamikazes[k].traitement_k(etge,taillemx,taillemy,joueurx,joueury,mapobj,ma,false);
          self.kamikazes[k].particle.Render_ennemi(myform._3D_device);
        end;
    end;
  self.k := true;
  self.w := false;
  if length(self.warriors) > 0 then
    begin
      for w := low(self.warriors) to high(self.warriors) do
        begin
          if self.warriors[w].peur in [0..3] then
            self.warriors[w].traitement_w(etge,taillemx,taillemy,joueurx,joueury,mapobj,ma)
          else
            if self.warriors[w].peur in [4..7] then
              self.warriors[w].traitement_w(etge,taillemx,taillemy,joueurx,joueury,mapobj,ma)
            else
              self.warriors[w].traitement_w(etge,taillemx,taillemy,joueurx,joueury,mapobj,ma);
          self.warriors[w].particle.Render_ennemi(myform._3D_device);
        end;
    end;
  self.w := true;
end;

function C_ennemis.acces(i,tab : integer) : t_nutella;
begin
  case tab of
    0 : begin
      result.pos.x := cyphers[i].posi;
      result.pos.y := cyphers[i].posj;
      result.emplacement.x := cyphers[i].emplacement.x;
      result.emplacement.y := cyphers[i].emplacement.y;
    end;
    1 : begin
      result.pos.x := kamikazes[i].posi;
      result.pos.y := kamikazes[i].posj;
      result.emplacement.x := kamikazes[i].emplacement.x;
      result.emplacement.y := kamikazes[i].emplacement.y;
    end;
    2 : begin
      result.pos.x := warriors[i].posi;
      result.pos.y := warriors[i].posj;
      result.emplacement.x := warriors[i].emplacement.x;
      result.emplacement.y := warriors[i].emplacement.y;
    end;
  end;
end;

function C_ennemis.longueur(tab : integer) : integer;
begin
  case tab of
    0 : begin
      result := high(self.cyphers);
    end;
    1 : begin
      result := high(self.kamikazes);
    end;
    2 : begin
      result := high(self.warriors);
    end;
  end;
end;
////////////////////////////////////////////////////////////////////////////////
//                                 C_ennemi                                   //
////////////////////////////////////////////////////////////////////////////////

function C_ennemi.traitement(etge,tx,ty,joueurx,joueury : integer ;var mapobj : t_map ;var ma : t_map_obj ; kam : boolean) : boolean;
var
  i,j : integer;
  d : t_move;
begin
  result := false;
  if self.thread.is_finished then
    begin
      self.bouge.init(30000);
      if self.timer.test then
        begin
          d := thread.fred.retourne_ck(self.emplacement.x,self.emplacement.y,etge,mapobj);
          if (d.x <> self.emplacement.x) or (d.y <> self.emplacement.y) then
            begin
              if myplayer.game_type = 's' then
                myplayer.clientorserveur.send_ennemi_move(inttostr(emplacement.x), inttostr(emplacement.y), inttostr(etge), inttostr(d.x), inttostr(d.y), inttostr(etge));
              mapobj[etge,self.emplacement.x,self.emplacement.y]._type := 'none';
              mapobj[etge,self.emplacement.x,self.emplacement.y].nom := 'none';
              self.emplacement := d;
              ma[petg][posi].tab_etage[posj].x := self.emplacement.x;
              ma[petg][posi].tab_etage[posj].y := self.emplacement.y;
              mapobj[etge,self.emplacement.x,self.emplacement.y] := ma[petg][posi].objet;
              self.frequence := getcurrenttime;
            end;
          if length(thread.fred.chemin) = 0 then
            begin
              self.thread.finish;
              self.timer.init(5000);
            end;
        end;
    end
  else
    begin
      if self.bouge.test then
        begin
          self.thread.init(self.emplacement.x,self.emplacement.y,self.dep.x,self.dep.y,etge,tx,ty,ma);
          self.thread.Execute;
          self.timer.init(100);
        end
      else
        begin
      if self.timer.test then
        begin
          self.orientation := (self.orientation + 1) mod 4;
        end;
    end;
  case self.orientation of
    0 : begin
      if (joueurx >= self.emplacement.x-(self.tlargeur div 2)) and
        (joueurx <= self.emplacement.x+(self.tlargeur div 2)) and
        (joueury <= self.emplacement.y) and
        (joueury >= self.emplacement.y-self.tlongueur)
      then
        result := true;
    end;
    1 : begin
      if (joueurx >= self.emplacement.x-(self.tlargeur div 2)) and
        (joueurx <= self.emplacement.x+(self.tlargeur div 2)) and
        (joueury <= self.emplacement.y) and
        (joueury >= self.emplacement.y-self.tlongueur)
      then
        result := true;
    end;
    2 : begin
      if (joueurx >= self.emplacement.x-(self.tlargeur div 2)) and
        (joueurx <= self.emplacement.x+(self.tlargeur div 2)) and
        (joueury >= self.emplacement.y) and
        (joueury <= self.emplacement.y+self.tlongueur)
      then
        result := true;
    end;
    3 : begin
      if (joueury >= self.emplacement.y-(self.tlargeur div 2)) and
        (joueury <= self.emplacement.y+(self.tlargeur div 2)) and
        (joueurx >= self.emplacement.x) and
        (joueurx <= self.emplacement.x+self.tlongueur)
      then
        result := true;
    end;
  end;
  if result then
    begin
      self.thread.finish;
      i := random(length(mapobj[etge]));
      j := random(length(mapobj[etge][i]));
      thread.init(self.emplacement.x,self.emplacement.y,i,j,etge,tx,ty,ma);
      thread.execute;
      self.timer.init(100);
      self.frequence := getcurrenttime;
    end;
    end;
end;

procedure C_ennemi.traitement_k(etge,tx,ty,joueurx,joueury : integer ;var mapobj : t_map ;var ma : t_map_obj ; kam : boolean);
var
  d : t_move;
begin
  if thread.is_finished then
    begin
      if self.timer.test then
        begin
          d := thread.fred.retourne_ck(self.emplacement.x,self.emplacement.y,etge,mapobj);
          if (d.x <> self.emplacement.x) or (d.y <> self.emplacement.y) then
            begin
              if myplayer.game_type = 's' then
                myplayer.clientorserveur.send_ennemi_move(inttostr(emplacement.x), inttostr(emplacement.y), inttostr(etge), inttostr(d.x), inttostr(d.y), inttostr(etge));
              mapobj[etge,self.emplacement.x,self.emplacement.y]._type := 'none';
              mapobj[etge,self.emplacement.x,self.emplacement.y].nom := 'none';
              self.emplacement := d;
              ma[petg][posi].tab_etage[posj].x := self.emplacement.x;
              ma[petg][posi].tab_etage[posj].y := self.emplacement.y;
              mapobj[etge,self.emplacement.x,self.emplacement.y] := ma[petg][posi].objet;
              self.bouge.init(5000);
            end;
          if length(thread.fred.chemin) = 0 then
            begin
              self.thread.finish;
              self.bouge.init(5000);
            end;
        end;
    end;
  //else
    //begin
      if kam or self.vu then
        begin
        if (5 > (sqrt(((joueurx-self.emplacement.x)*(joueurx-self.emplacement.x))+((joueury-self.emplacement.y)*(joueury-self.emplacement.y))))) and (self.attaque.test) then
          begin
           self.particle.add_part_ennemi(100,self.emplacement.x,self.emplacement.y,joueurx,joueury);
           myplayer.suicide(10,self.emplacement.x,self.emplacement.y,joueurx,joueury);
           self.attaque.init(4000);
           self.thread.finish;
//           self.timer.init(5000);
           self.bouge.init(5000);
          end
        else
          begin
            thread.init(self.emplacement.x,self.emplacement.y,joueurx,joueury,etge,tx,ty,ma);
            thread.Execute;
            self.timer.init(200);
            self.vu := false;
          end;
        end
      else
        begin
          if self.bouge.test then
            begin
              self.thread.init(self.emplacement.x,self.emplacement.y,self.dep.x,self.dep.y,etge,tx,ty,ma);
              self.thread.Execute;
              self.timer.init(200);
            end
          else
            begin
              self.orientation := random(4);
              self.vu := false;
              case self.orientation of
                0 : begin
                  if (joueurx >= self.emplacement.x-(self.tlargeur div 2)) and
                    (joueurx <= self.emplacement.x+(self.tlargeur div 2)) and
                    (joueury <= self.emplacement.y) and
                    (joueury >= self.emplacement.y-self.tlongueur)
                  then
                    begin
                      self.vu := true;
                      self.bouge.init(5000);
                    end;
                end;
                1 : begin
                  if (joueurx >= self.emplacement.x-(self.tlargeur div 2)) and
                    (joueurx <= self.emplacement.x+(self.tlargeur div 2)) and
                    (joueury <= self.emplacement.y) and
                    (joueury >= self.emplacement.y-self.tlongueur)
                  then
                    begin
                      self.vu := true;
                      self.bouge.init(5000);
                    end;
                end;
                2 : begin
                  if (joueurx >= self.emplacement.x-(self.tlargeur div 2)) and
                    (joueurx <= self.emplacement.x+(self.tlargeur div 2)) and
                    (joueury >= self.emplacement.y) and
                    (joueury <= self.emplacement.y+self.tlongueur)
                  then
                    begin
                      self.vu := true;
                      self.bouge.init(5000);
                    end;
                end;
                3 : begin
                  if (joueury >= self.emplacement.y-(self.tlargeur div 2)) and
                    (joueury <= self.emplacement.y+(self.tlargeur div 2)) and
                    (joueurx >= self.emplacement.x) and
                    (joueurx <= self.emplacement.x+self.tlongueur)
                  then
                    begin
                      self.vu := true;
                      self.bouge.init(5000);
                    end;
                end;
              end;
            end;
        end;
    //end;
end;

procedure C_ennemi.traitement_w(etge,tx,ty,joueurx,joueury : integer ;var mapobj : t_map ;var ma : t_map_obj);
var
  d : t_move;
begin
  self.vu := false;
  case self.orientation of
    0 : begin
      if (joueurx >= self.emplacement.x-(self.tlargeur div 2)) and
        (joueurx <= self.emplacement.x+(self.tlargeur div 2)) and
        (joueury <= self.emplacement.y) and
        (joueury >= self.emplacement.y-self.tlongueur)
      then
        self.vu := true;
    end;
    1 : begin
      if (joueurx >= self.emplacement.x-(self.tlargeur div 2)) and
        (joueurx <= self.emplacement.x+(self.tlargeur div 2)) and
        (joueury <= self.emplacement.y) and
        (joueury >= self.emplacement.y-self.tlongueur)
      then
        self.vu := true;
    end;
    2 : begin
      if (joueurx >= self.emplacement.x-(self.tlargeur div 2)) and
        (joueurx <= self.emplacement.x+(self.tlargeur div 2)) and
        (joueury >= self.emplacement.y) and
        (joueury <= self.emplacement.y+self.tlongueur)
      then
        self.vu := true;
    end;
    3 : begin
      if (joueury >= self.emplacement.y-(self.tlargeur div 2)) and
        (joueury <= self.emplacement.y+(self.tlargeur div 2)) and
        (joueurx >= self.emplacement.x) and
        (joueurx <= self.emplacement.x+self.tlongueur)
      then
        self.vu := true;
    end;
  end;
  if (thread.is_finished) and (not self.vu) then
    begin
      if self.timer.test then
        begin
          d := thread.fred.retourne_ck(self.emplacement.x,self.emplacement.y,etge,mapobj);
          if (d.x <> self.emplacement.x) or (d.y <> self.emplacement.y) then
            begin
              //Envoi nouvelle position de l'ennemi
              if myplayer.game_type = 's' then
                myplayer.clientorserveur.send_ennemi_move(inttostr(emplacement.x), inttostr(emplacement.y), inttostr(etge), inttostr(d.x), inttostr(d.y), inttostr(etge));
              mapobj[etge,self.emplacement.x,self.emplacement.y]._type := 'none';
              mapobj[etge,self.emplacement.x,self.emplacement.y].nom := 'none';
              self.emplacement := d;
              ma[petg][posi].tab_etage[posj].x := self.emplacement.x;
              ma[petg][posi].tab_etage[posj].y := self.emplacement.y;
              mapobj[etge,self.emplacement.x,self.emplacement.y] := ma[petg][posi].objet;
            end;
          if length(thread.fred.chemin) = 0 then
            begin
              self.thread.finish;
              self.timer.init(5000);
            end;
        end;
    end
  else
    begin
      if self.vu and self.attaque.test then
        begin
          self.particle.add_part_ennemi(100,self.emplacement.x,self.emplacement.y,joueurx,joueury);
          myplayer.suicide(10,self.emplacement.x,self.emplacement.y,joueurx,joueury);
        end
      else
        if self.timer.test then
          begin
            self.thread.init(self.emplacement.x,self.emplacement.y,random(tx),random(ty),etge,tx,ty,ma);
            self.thread.Execute;
            self.timer.init(200);
          end;
    end;
end;



end.
